﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//
using System.Windows.Forms;
using System.IO;

namespace Mp3Edit
{
    public struct TRACK
    {
        public string TITLE;
        public string PERFORMER;
    }

    public class ReadCueFile
    {
        //
        public string PERFORMER = "";
        public string TITLE = "";
        public string FILE = "";
        public string DATE = "";
        //
        public TRACK[] TRACKS = null;
        //
        public ReadCueFile()
        {
        }

        public bool ReadCue(string fileName)
        {
            StreamReader sr1 = null;

            PERFORMER = "";
            TITLE = "";
            FILE = "";
            DATE = "";
            //
            TRACKS = null;
            //
            try
            {
                sr1 = new StreamReader(fileName, Encoding.Default);
                //
                //
                if (isCueMultiFile(sr1))
                {
                    parseMultiFile(sr1);
                }
                else
                {
                    parseMultiTitle(sr1);
                }
                //
                sr1.Close();
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message, "ReadCue()", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
            //
            return true;
        }
        //
        private bool parseMultiFile(StreamReader sr1)
        {
            string[] ss = null;
            List<TRACK> lt = new List<TRACK>();
            TRACK t = new TRACK();
            //
            for (; ; )
            {
                string s = sr1.ReadLine();
                if (null == s) break;
                //
                s = s.Trim();
                if ("" == s) continue;
                //ss = s.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                ss = splitCueLine(s);
                if (ss.Length < 3) continue;
                //
                if ("" == PERFORMER)
                {
                    if (0 == string.Compare("PERFORMER", ss[0], true))
                    {
                        if(ss.Length > 1)PERFORMER = ss[1].Trim();
                    }
                }
                if ("" == TITLE)
                {
                    if (0 == string.Compare("TITLE", ss[0], true))
                    {
                        if (ss.Length > 1) TITLE = ss[1].Trim();
                    }
                }
                //
                if (0 == string.Compare("FILE", ss[0], true))
                {
                    t.PERFORMER = "";
                    t.TITLE = Path.GetFileNameWithoutExtension(ss[1]);
                    lt.Add(t);
                }
                //
            }
            //
            TRACKS = lt.ToArray<TRACK>();
            //
            return true;
        }
        //
                //
        private bool parseMultiTitle(StreamReader sr1)
        {
            bool isFILE = false;
            string[] ss = null;
            List<TRACK> lt = new List<TRACK>();
            TRACK t = new TRACK();
            string tmpPERFORMER = "";
            //
            for (; ; )
            {
                string s = sr1.ReadLine();
                if (null == s) break;
                //
                s = s.Trim();
                if ("" == s) continue;
                //ss = s.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                ss = splitCueLine(s);
                if (1 > ss.Length) continue;
                //
                if (!isFILE)
                {
                    switch (ss[0].ToUpper())
                    {
                        case "REM":
                            if ("DATE" == ss[1])
                            {
                                if (ss.Length > 2)DATE = ss[2];
                            }
                            break;
                        case "PERFORMER":
                            if (ss.Length > 1) PERFORMER = ss[1].Trim();
                            break;
                        case "TITLE":
                            if (ss.Length > 1) TITLE = ss[1].Trim();
                            break;
                        case "FILE":
                            isFILE = true;
                            continue;
                    }
                }
                //
                if (isFILE)
                {
                    if (2 > ss.Length) continue;
                    //
                    switch (ss[0].ToUpper())
                    {
                        case "TITLE":
                            t.PERFORMER = tmpPERFORMER; tmpPERFORMER = "";
                            t.TITLE = ss[1];
                            lt.Add(t);
                            break;
                        case "PERFORMER":
                            tmpPERFORMER = ss[1];
                            break;
                    }
                }
                //
            }
            //
            TRACKS = lt.ToArray<TRACK>();
            //
            return true;
        }
        //
        //
        private bool isCueMultiFile(StreamReader sr1)
        {
            int kount = 0;
            //
            string[] ss = null;
            for (; ; )
            {
                string s = sr1.ReadLine();
                if (null == s) break;
                //
                s = s.Trim();
                if ("" == s) continue;
                ss = s.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                if (1 > ss.Length) continue;
                //
                if (0 == string.Compare("FILE", ss[0], true)) kount++;
                //
            }
            //
            sr1.BaseStream.Seek(0, SeekOrigin.Begin);
            return kount > 1;
        }
        //
        private string [] splitCueLine(string line)
        {
            line = line.Trim();
            //
            List<string> ls = new List<string>();
            string tmp = "";
            bool isInParen = false;
            bool isWhiteSpace = false;
            foreach (char c in line)
            {
                if (isInParen)
                {
                    if ('\"' == c)
                    {
                        ls.Add(tmp);
                        tmp = "";
                        isInParen = false;
                        continue;
                    }
                    else
                    {
                        tmp += c;
                    }
                }
                else
                {
                    if ('\"' == c)
                    {
                        tmp = "";
                        isInParen = true;
                        isWhiteSpace = false;
                        continue;
                    }
                    if (Char.IsWhiteSpace(c))
                    {
                        if (isWhiteSpace) continue;
                        ls.Add(tmp);
                        tmp = "";
                        isWhiteSpace = true;
                        continue;
                    }
                    else
                    {
                        isWhiteSpace = false;
                        tmp += c;
                    }
                }
            }
            //
            if ("" != tmp) ls.Add(tmp);
            //
            return ls.ToArray();
        }
        //
    }//class
}//namespace
